#ifndef DTU_DATA_COLLECT_H
#define DTU_DATA_COLLECT_H

#include "dtu_common.h"
#include "dtu_modbus.h"

/* 数据点配置 */
typedef struct {
    char name[64];            /* 数据点名称 */
    char description[128];    /* 数据点描述 */
    uint8_t slave_id;         /* 从站地址 */
    modbus_function_code_t function_code; /* 功能码 */
    uint16_t address;         /* 寄存器地址 */
    uint16_t count;           /* 寄存器数量 */
    data_type_t data_type;    /* 数据类型 */
    byte_order_t byte_order;  /* 字节序 */
    float scale;              /* 缩放因子 */
    float offset;             /* 偏移量 */
    char unit[16];            /* 单位 */
    bool enabled;             /* 是否启用 */
} data_point_t;

/* 设备配置 */
typedef struct {
    char name[64];            /* 设备名称 */
    char description[128];    /* 设备描述 */
    uint8_t slave_id;         /* 从站地址 */
    int serial_id;            /* 串口ID: 1=RS485, 2=RS232 */
    int timeout;              /* 超时时间(ms) */
    int retry_count;          /* 重试次数 */
    bool enabled;             /* 是否启用 */
    char poll_string[256];    /* 16进制轮询字符串 */
    bool crc_enable;          /* CRC校验使能 */
    data_point_t* points;     /* 数据点数组 */
    int point_count;          /* 数据点数量 */
} device_config_t;

/* 数据值结构 */
typedef struct {
    char name[64];            /* 数据点名称 */
    data_type_t type;         /* 数据类型 */
    union {
        int16_t i16_value;
        uint16_t u16_value;
        int32_t i32_value;
        uint32_t u32_value;
        float float_value;
        double double_value;
        bool bool_value;
    } value;
    char unit[16];            /* 单位 */
    time_t timestamp;         /* 时间戳 */
    bool valid;               /* 数据有效性 */
    int error_code;           /* 错误码 */
} data_value_t;

/* 采集结果结构 */
typedef struct {
    char device_name[64];     /* 设备名称 */
    uint8_t slave_id;         /* 从站地址 */
    time_t collect_time;      /* 采集时间 */
    data_value_t* values;     /* 数据值数组 */
    int value_count;          /* 数据值数量 */
    int success_count;        /* 成功采集数量 */
    int error_count;          /* 错误数量 */

    /* 原始16进制数据 - 用于直接转发 */
    char raw_hex_data[512];   /* 原始16进制响应数据 */
    int raw_data_length;      /* 原始数据长度 */
    bool has_raw_data;        /* 是否包含原始数据 */
} collect_result_t;

/* 采集统计信息 */
typedef struct {
    uint32_t total_collections;   /* 总采集次数 */
    uint32_t successful_collections; /* 成功采集次数 */
    uint32_t failed_collections;  /* 失败采集次数 */
    uint32_t total_points;        /* 总数据点数 */
    uint32_t successful_points;   /* 成功采集点数 */
    uint32_t failed_points;       /* 失败采集点数 */
    time_t last_collect_time;     /* 最后采集时间 */
    time_t start_time;            /* 开始时间 */
} collect_stats_t;

/* 采集管理器结构 */
typedef struct {
    device_config_t* devices;     /* 设备配置数组 */
    int device_count;             /* 设备数量 */
    modbus_context_t* modbus_ctx_rs485; /* RS485 Modbus上下文 */
    modbus_context_t* modbus_ctx_rs232; /* RS232 Modbus上下文 */
    collect_config_t config;      /* 采集配置 */
    pthread_t collect_thread;     /* 采集线程 */
    pthread_mutex_t mutex;        /* 互斥锁 */
    bool initialized;             /* 初始化标志 */
    bool running;                 /* 运行状态 */
    collect_stats_t stats;        /* 统计信息 */

    /* 回调函数 */
    void (*data_callback)(const collect_result_t* result, void* user_data);
    void* callback_user_data;
} collect_manager_t;

/* 函数声明 */

/**
 * @brief 初始化数据采集管理器
 * @param config 采集配置
 * @param rs485_config RS485串口配置
 * @param rs232_config RS232串口配置
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_init(const collect_config_t* config,
                                  const serial_config_t* rs485_config,
                                  const serial_config_t* rs232_config);

/**
 * @brief 销毁数据采集管理器
 */
void dtu_data_collect_cleanup(void);

/**
 * @brief 启动数据采集
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_start(void);

/**
 * @brief 停止数据采集
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_stop(void);

/**
 * @brief 手动执行一次数据采集（用于云端轮询）
 * @param device_id 设备ID
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_execute_once(int device_id);

/**
 * @brief 添加设备配置
 * @param device 设备配置
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_add_device(const device_config_t* device);

/**
 * @brief 移除设备配置
 * @param device_name 设备名称
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_remove_device(const char* device_name);

/**
 * @brief 添加数据点
 * @param device_name 设备名称
 * @param point 数据点配置
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_add_point(const char* device_name, const data_point_t* point);

/**
 * @brief 移除数据点
 * @param device_name 设备名称
 * @param point_name 数据点名称
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_remove_point(const char* device_name, const char* point_name);

/**
 * @brief 重新加载设备配置
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_reload_devices(void);

/**
 * @brief 手动触发数据采集
 * @param device_name 设备名称，NULL表示所有设备
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_trigger(const char* device_name);

/**
 * @brief 获取最新采集结果
 * @param device_name 设备名称
 * @param result 输出采集结果
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_get_result(const char* device_name, collect_result_t* result);

/**
 * @brief 获取采集统计信息
 * @param stats 输出统计信息
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_get_stats(collect_stats_t* stats);

/**
 * @brief 重置采集统计信息
 */
void dtu_data_collect_reset_stats(void);

/**
 * @brief 设置数据回调函数
 * @param callback 回调函数
 * @param user_data 用户数据
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_set_callback(void (*callback)(const collect_result_t* result, void* user_data), 
                                          void* user_data);

/**
 * @brief 获取设备列表
 * @param devices 输出设备数组
 * @param max_count 最大设备数量
 * @return 实际设备数量
 */
int dtu_data_collect_get_devices(device_config_t* devices, int max_count);

/**
 * @brief 启用/禁用设备
 * @param device_name 设备名称
 * @param enabled 是否启用
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_enable_device(const char* device_name, bool enabled);

/**
 * @brief 启用/禁用数据点
 * @param device_name 设备名称
 * @param point_name 数据点名称
 * @param enabled 是否启用
 * @return DTU_OK 成功，其他值失败
 */
dtu_error_t dtu_data_collect_enable_point(const char* device_name, const char* point_name, bool enabled);

/**
 * @brief 释放采集结果
 * @param result 采集结果
 */
void dtu_data_collect_free_result(collect_result_t* result);

/**
 * @brief 数据类型转换为字符串
 * @param type 数据类型
 * @return 类型字符串
 */
const char* dtu_data_type_string(data_type_t type);

/**
 * @brief 从字符串解析数据类型
 * @param str 类型字符串
 * @return 数据类型
 */
data_type_t dtu_data_type_from_string(const char* str);

#endif /* DTU_DATA_COLLECT_H */
